package org.dromara.netbar.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.dromara.common.core.constant.NetbarConstants;
import org.dromara.common.core.utils.AssertUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.netbar.domain.bo.NetbarSeatTypeBo;
import org.dromara.netbar.domain.vo.NetbarMemberVo;
import org.dromara.netbar.domain.vo.NetbarSeatTypeVo;
import org.dromara.netbar.service.INetbarSeatTypeService;
import org.springframework.stereotype.Service;
import org.dromara.netbar.domain.bo.NetbarClientBo;
import org.dromara.netbar.domain.vo.NetbarClientVo;
import org.dromara.netbar.domain.NetbarClient;
import org.dromara.netbar.mapper.NetbarClientMapper;
import org.dromara.netbar.service.INetbarClientService;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 客机管理Service业务层处理
 *
 * @author Lion Li
 * @date 2025-07-04
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class NetbarClientServiceImpl implements INetbarClientService {

    private final NetbarClientMapper baseMapper;

    private final INetbarSeatTypeService netbarSeatTypeService;

    /**
     * 查询客机管理
     *
     * @param clientId 主键
     * @return 客机管理
     */
    @Override
    public NetbarClientVo queryById(Long clientId){
        return baseMapper.selectVoById(clientId);
    }

    /**
     * 分页查询客机管理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 客机管理分页列表
     */
    @Override
    public TableDataInfo<NetbarClientVo> queryPageList(NetbarClientBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<NetbarClient> lqw = buildQueryWrapper(bo);
        Page<NetbarClientVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (CollectionUtil.isNotEmpty(result.getRecords())) {
            List<NetbarSeatTypeVo> netbarSeatTypeVos = netbarSeatTypeService.queryList(new NetbarSeatTypeBo());
            Map<String, Object> clientRedisMap = null;
            String clientRedisKey = result.getRecords().get(0).getTenantId() + NetbarConstants.ONLINE_CLIENT_KEY;
            Map<String, Map<String,Object>> cacheMap = RedisUtils.getCacheMap(clientRedisKey);
            Long startTime;
            for (NetbarClientVo record : result.getRecords()) {
                record.setSeatTypeName(netbarSeatTypeVos.stream().filter(item -> item.getSeatTypeId().equals(record.getSeatTypeId())).findFirst().map(NetbarSeatTypeVo::getSeatTypeName).orElse(""));
                // clientRedisMap = RedisUtils.getCacheObject(record.getTenantId() + ":online_client:" + record.getClientId());
                clientRedisMap =  cacheMap.get(record.getClientId().toString());
                if(clientRedisMap != null){
                    startTime = (Long) clientRedisMap.get("startTime");
                    record.setOnlineTimeStr(Duration.ofMillis(System.currentTimeMillis() - startTime).toHours() + "小时" + Duration.ofMillis(System.currentTimeMillis() - startTime).toMinutesPart() + "分钟");
                }
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的客机管理列表
     *
     * @param bo 查询条件
     * @return 客机管理列表
     */
    @Override
    public List<NetbarClientVo> queryList(NetbarClientBo bo) {
        LambdaQueryWrapper<NetbarClient> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<NetbarClient> buildQueryWrapper(NetbarClientBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<NetbarClient> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(NetbarClient::getClientId);
        lqw.eq(StringUtils.isNotBlank(bo.getClientNo()), NetbarClient::getClientNo, bo.getClientNo());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), NetbarClient::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增客机管理
     *
     * @param bo 客机管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(NetbarClientBo bo) {
        NetbarClient add = MapstructUtils.convert(bo, NetbarClient.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setClientId(add.getClientId());
        }
        return flag;
    }

    /**
     * 修改客机管理
     *
     * @param bo 客机管理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(NetbarClientBo bo) {
        NetbarClient update = MapstructUtils.convert(bo, NetbarClient.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(NetbarClient entity){
        //TODO 做一些数据校验,如唯一约束
        AssertUtils.notNull(entity.getSeatTypeId(), "请选择座位类型");
        AssertUtils.notEmpty(entity.getClientNo(), "请输入座位编号");
        AssertUtils.notEmpty(entity.getMacAddress(), "请输入MAC地址");
        // mac地址查重
        LambdaQueryWrapper<NetbarClient> lambdaQueryWrapper = new LambdaQueryWrapper<NetbarClient>()
            .ne(null != entity.getClientId(), NetbarClient::getClientId, entity.getClientId())
            .eq(NetbarClient::getMacAddress, entity.getMacAddress());
        AssertUtils.isTrue(baseMapper.selectCount(lambdaQueryWrapper) == 0, "该MAC地址已存在");
        // clientNo查重
        lambdaQueryWrapper.clear();
        lambdaQueryWrapper.ne(null != entity.getClientId(), NetbarClient::getClientId, entity.getClientId())
            .eq(NetbarClient::getClientNo, entity.getClientNo());
        AssertUtils.isTrue(baseMapper.selectCount(lambdaQueryWrapper) == 0, "该座位编号已存在");
    }

    /**
     * 校验并批量删除客机管理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public NetbarClientVo getClient(String tenantId, String clientNo) {
        return baseMapper.selectVoOne(new LambdaUpdateWrapper<NetbarClient>()
            .eq(NetbarClient::getTenantId, tenantId)
            .eq(NetbarClient::getClientNo, clientNo));
    }

    @Override
    public NetbarClientVo getClientByMacAddress(String tenantId, String macAddress) {
        return baseMapper.selectVoOne(new LambdaUpdateWrapper<NetbarClient>()
            .eq(NetbarClient::getTenantId, tenantId)
            .eq(NetbarClient::getMacAddress, macAddress)
            .eq(NetbarClient::getDelFlag, "0"));
    }

    @Override
    public Boolean updateClientStatus(String tenantId, Long clientId, String status) {
        LambdaUpdateWrapper<NetbarClient> netbarClientLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        netbarClientLambdaUpdateWrapper.eq(NetbarClient::getTenantId, tenantId)
            .eq(NetbarClient::getClientId, clientId)
            .set(NetbarClient::getStatus, status);
        return baseMapper.update(netbarClientLambdaUpdateWrapper) > 0;
    }

    @Override
    public List<NetbarClientVo> getClientAll(String tenantId) {
        List<NetbarClientVo> netbarClientVos = baseMapper.selectClientWithSeatType(tenantId);
        return netbarClientVos;
    }

    @Override
    public void bindClientOpen(String tenantId, Long clientId) {
        LambdaUpdateWrapper<NetbarClient> netbarClientLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        netbarClientLambdaUpdateWrapper.eq(NetbarClient::getTenantId, tenantId)
            .eq(NetbarClient::getClientId, clientId)
            .set(NetbarClient::getStatus, "1");
        baseMapper.update(netbarClientLambdaUpdateWrapper);
    }
}
